package com.boruan.shengtangfeng.core.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang3.time.DateFormatUtils;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 * 
 * @author ThinkGem
 * @version 2013-3-15
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

	private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd",
			"yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "ss mm HH dd MM ?" };

	public static List<String> getAllDay() {
		List<String> list = new ArrayList<>();
		Date d = new Date();
		Date date = getMonthStart(d);
		Date monthEnd = getMonthEnd(d);
		while (!date.after(monthEnd)) {
			list.add(sdf.format(date));
			date = getNext(date);
		}
		return list;
	}

	/**
	 * 获取发布时间距当前时间的字符串
	 * @param date
	 * @return
	 */
	public static String getShortTime(Date date) {
        String shortString = null;
        long now = Calendar.getInstance().getTimeInMillis();
        if(date == null) {
                return shortString;
        }
        long delTime = (now - date.getTime()) / 1000;
        if (delTime > 365 * 24 * 60 * 60) {
                shortString = (int) (delTime / (365 * 24 * 60 * 60)) + "年前";
        } else if (delTime > 24 * 60 * 60) {
                shortString = (int) (delTime / (24 * 60 * 60)) + "天前";
        } else if (delTime > 60 * 60) {
                shortString = (int) (delTime / (60 * 60)) + "小时前";
        } else if (delTime > 60) {
                shortString = (int) (delTime / (60)) + "分前";
        } else if (delTime > 1) {
                shortString = delTime + "秒前";
        } else {
                shortString = "1秒前";
        }
        return shortString;
    }
	public static Date getMonthStart(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int index = calendar.get(Calendar.DAY_OF_MONTH);
		calendar.add(Calendar.DATE, (1 - index));
		return calendar.getTime();
	}

	public static Date getMonthEnd(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, 1);
		int index = calendar.get(Calendar.DAY_OF_MONTH);
		calendar.add(Calendar.DATE, (-index));
		return calendar.getTime();
	}

	public static Date getNext(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);
		return calendar.getTime();
	}

	public static Date getPre(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, -1);
		return calendar.getTime();
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd）
	 */
	public static String getDate() {
		return getDate("yyyy-MM-dd");
	}

	/**
	 * 得到当前日期字符串 格式（yyyyMMdd）
	 */
	public static String getDateToStr() {
		return getDate("yyyy-MM-dd");
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String getDate(String pattern) {
		return DateFormatUtils.format(new Date(), pattern);
	}

	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate = null;
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString(),Locale.CHINESE);
		} else {
			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd",Locale.CHINESE);
		}
		return formatDate;
	}

	/**
	 * 得到当前时间字符串 格式（HH:mm:ss）
	 */
	public static String getTime() {
		return formatDate(new Date(), "HH:mm:ss");
	}

	/**
	 * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String getDateTime() {
		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前年份字符串 格式（yyyy）
	 */
	public static String getYear() {
		return formatDate(new Date(), "yyyy");
	}

	/**
	 * 得到当前月份字符串 格式（MM）
	 */
	public static String getMonth() {
		return formatDate(new Date(), "MM");
	}

	/**
	 * 得到当天字符串 格式（dd）
	 */
	public static String getDay() {
		return formatDate(new Date(), "dd");
	}

	/**
	 * 得到当前星期字符串 格式（E）星期几
	 */
	public static String getWeek() {
		return formatDate(new Date(), "E");
	}

	/**
	 * 日期型字符串转化为日期 格式 { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm",
	 * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" }
	 */
	public static Date parseDate(Object str) {
		if (str == null) {
			return null;
		}
		try {
			return parseDate(str.toString(), parsePatterns);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取过去的天数
	 * 
	 * @param date
	 * @return
	 */
	public static long pastDays(Date date) {
		long t = new Date().getTime() - date.getTime();
		return t / (24 * 60 * 60 * 1000);
	}

	/**
	 * 过去的分钟
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static long pastMinutes(Date date1, Date date2) {
		long t = date1.getTime() - date2.getTime();
		return t / (60 * 1000);
	}

	/**
	 * 得到几天前的日期
	 * 
	 * @param d
	 * @param day
	 * @return
	 */
	public static Date getDateBefore(Date d, int day) {
		Calendar now = Calendar.getInstance();
		now.setTime(d);
		now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
		return now.getTime();
	}

	/**
	 *
	 * getDateAfter(获取之后几天)
	 *
	 * @Title: getDateAfter @author :taoq @param @param today @param @param
	 *         day @param @return 设定文件 @return Date 返回类型 @throws
	 */
	public static Date getDateAfter(Date today, int day) {
		Calendar now = Calendar.getInstance();
		now.setTime(today);
		now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
		return now.getTime();
	}

	/**
	 * 得到每一天日期
	 * 
	 * @param beginDay
	 * @param EndDay
	 * @param type     1:yyyy-MM-dd 2：MM月dd日
	 * @return
	 */
	public static String getEveryDate(Date beginDay, Date EndDay, int type) {
		String strDate = null;
		SimpleDateFormat sdf = null;
		if (type == 1) {
			sdf = new SimpleDateFormat("yyyy-MM-dd");
		} else {
			sdf = new SimpleDateFormat("MM月dd日");
		}
		long t = (EndDay.getTime() - beginDay.getTime()) / (24 * 60 * 60 * 1000); // 相差天数
		for (int i = (int) t; i >= 0; i--) {
			if (strDate == null) {
				strDate = sdf.format(getDateBefore(EndDay, i));
			} else {
				strDate += "," + sdf.format(getDateBefore(EndDay, i));
			}
		}
		return strDate;
	}

	/**
	 * 两个日期相减，获取两者之间的时间间隔（秒）
	 *
	 * @param date1 被减时间
	 * @param date2 减时间
	 * @return 秒数
	 */
	public static int subSecond(Date date1, Date date2) {
		// 实例化Calendar
		Calendar calendar = Calendar.getInstance();
		// 获取第一个日期对应的毫秒数
		calendar.setTime(date1);
		long timethis = calendar.getTimeInMillis();
		// 获取第二个日期对应的毫秒数
		calendar.setTime(date2);
		long timeend = calendar.getTimeInMillis();
		// 计算两个日期的间隔时间
		long theday = (timethis - timeend) / 1000;
		return (int) theday;
	}

	/**
	 * Date字符串转ZonedDateTime
	 *
	 * @param dataTime 字符串时间
	 * @return ZonedDateTime
	 */
	public static ZonedDateTime dateTimeStrToZoned(String dateTime) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePatterns[1]);
		LocalDateTime localDateTime = LocalDateTime.parse(dateTime, formatter);
		return ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
	}

	/**
	 * Date字符串转ZonedDateTime
	 *
	 * @param dataTime 字符串时间
	 * @return ZonedDateTime
	 */
	public static ZonedDateTime dateTimeStrToZoned(String dateTime, String pattern) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
		LocalDate localDate = LocalDate.parse(dateTime, formatter);
		return localDate.atStartOfDay(ZoneId.systemDefault());
	}

	/**
	 * Date字符串转ZonedDateTime（time 和 amOrPm 不能同时为null time : 自定义时间部分； amOrPm : 0
	 * 上午-00:00:00; 1 下午-23:59:59）
	 *
	 * @param date   日期部分
	 * @param time   时间部分
	 * @param amOrPm 0 00:00:00/ 1 23:59:59
	 * @return ZonedDateTime
	 */
	public static ZonedDateTime dateTimeStrToZoned(String date, String time, Integer amOrPm) {
		String blankChar = " ";
		String dateTime = new String();
		if ((org.springframework.util.StringUtils.isEmpty(time) && amOrPm == null)
				|| (!org.springframework.util.StringUtils.isEmpty(time) && amOrPm != null)) {
			return null;
		} else if (!StringUtils.isEmpty(time)) {
			dateTime = date + blankChar + time;
		} else if (amOrPm != null && amOrPm.equals(0)) {
			dateTime = date + blankChar + "00:00:00";
		} else if (amOrPm != null && amOrPm.equals(1)) {
			dateTime = date + blankChar + "23:59:59";
		}
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePatterns[1]);
		LocalDateTime localDateTime = LocalDateTime.parse(dateTime, formatter);
		return ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
	}

	/**
	 * 获取当前时间的ZonedDateTime类型
	 *
	 * @param dataTime 字符串时间
	 * @return ZonedDateTime
	 */
	public static ZonedDateTime getZonedDateTime() {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePatterns[1]);
		LocalDateTime localDateTime = LocalDateTime.parse(getDate(parsePatterns[1]), formatter);
		return ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
	}

	/**
	 *
	 * getSecondBefore(获取之前几秒的时间)
	 * 
	 * @Title: getSecondBefore @author :taoq @param @param today @param @param
	 *         seconds @param @return 设定文件 @return Date 返回类型 @throws
	 */
	public static Date getSecondBefore(Date today, int seconds) {
		Calendar now = Calendar.getInstance();
		now.setTime(today);
		now.set(Calendar.SECOND, now.get(Calendar.SECOND) - seconds);
		return now.getTime();
	}

	/**
	 *
	 * getSecondBefore(获取之后几秒的时间)
	 * 
	 * @Title: getSecondBefore @author :taoq @param @param today @param @param
	 *         seconds @param @return 设定文件 @return Date 返回类型 @throws
	 */
	public static Date getSecondAfter(Date today, int seconds) {
		Calendar now = Calendar.getInstance();
		now.setTime(today);
		now.set(Calendar.SECOND, now.get(Calendar.SECOND) + seconds);
		return now.getTime();
	}

	/**
	 * Date字符串转ZonedDateTime（time 和 amOrPm 不能同时为null time : 自定义时间部分； amOrPm : 0
	 * 上午-00:00:00; 1 下午-23:59:59）
	 *
	 * @param date   日期部分
	 * @param time   时间部分
	 * @param amOrPm 0 00:00:00/ 1 23:59:59
	 * @return ZonedDateTime
	 */
	public static ZonedDateTime dateTimeStrToZoned123(String date, String time, Integer amOrPm) {
		String blankChar = " ";
		String dateTime = new String();
		if ((org.springframework.util.StringUtils.isEmpty(time) && amOrPm == null)
				|| (!org.springframework.util.StringUtils.isEmpty(time) && amOrPm != null)) {
			return null;
		} else if (!org.springframework.util.StringUtils.isEmpty(time)) {
			dateTime = date + blankChar + time;
		} else if (amOrPm != null && amOrPm.equals(0)) {
			dateTime = date + blankChar + "00:00:00";
		} else if (amOrPm != null && amOrPm.equals(1)) {
			dateTime = date + blankChar + "23:59:59";
		}
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(parsePatterns[1]);
		LocalDateTime localDateTime = LocalDateTime.parse(dateTime, formatter);
		return ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
	}

	/**
	 * 获取date的cron类型
	 *
	 * @param Date 字符串时间
	 * @return cron类型的日期
	 */
	public static String getCron(Date date) {
		String formatDate = "";
		formatDate = formatDate(date, parsePatterns[6]);
		return formatDate;
	}

	/**
	 * 获取当前时间的之后某个时间的cron类型
	 *
	 * @return cron类型的日期
	 */
	public static String getCron(Integer minute) {
		String formatTimeStr = "";
		Calendar nowTime = Calendar.getInstance();
		nowTime.add(Calendar.MINUTE, minute);
		formatTimeStr = formatDate(nowTime.getTime(), parsePatterns[6]);
		return formatTimeStr;
	}

	/**
	 * @Title: stampToDate
	 * @Description: 时间戳字符串
	 * @author duty
	 * @param simpleDate
	 * @return java.util.Date
	 */
	public static Date stampToDate(String simpleDate) {
		if (simpleDate == null) {
			return new Date();
		}

		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long lt = new Long(simpleDate);
		Date date = new Date(lt);
		String res = simpleDateFormat.format(date);
		return parseDate(res);
	}

	public String getDate(Date date) {

		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH) + 1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		return "" + year + month + day;
	}

	/**
	 * 传入总秒数，返回时间
	 * 
	 * @param second 秒
	 */
	public static String changeTime(int second) {
		int h = second / 3600;
		int m = (second % 3600) / 60;
		int s = (second % 3600) % 60;
		StringBuilder sb = new StringBuilder();
		if (h != 0) {
			sb.append(h + "小时");
		}
		if (m != 0) {
			sb.append(m + "分钟");
		}
		/*
		 * if(s != 0){ sb.append(s + "秒"); } else { sb.append("0秒"); }
		 */
		return sb.toString();
	}

	/**
	 * 判断日期是否是同一天
	 */
	public static boolean isSameDay(Date date1, Date date2) {
		if (date1 != null && date2 != null) {
			Calendar cal1 = Calendar.getInstance();
			cal1.setTime(date1);
			Calendar cal2 = Calendar.getInstance();
			cal2.setTime(date2);
			return isSameDay(cal1, cal2);
		} else {
			throw new IllegalArgumentException("The date must not be null");
		}
	}

	/**
	 * 
	 * 给定开始时间和结束时间，把中间的日期按照周分组
	 * 
	 * 第一种方法（目前就第一种方法好用没有Bug）
	 */
	public static List<String> groupByWeek(String a, String b) throws ParseException {
		List<String> time = new ArrayList<String>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date ad = null;
		Date bd = null;
		try {
			ad = sdf.parse(a);
			bd = sdf.parse(b);
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 使用默认时区和语言环境获得一个日历
		Calendar cl1 = Calendar.getInstance();
		cl1.setTime(ad);
		Calendar cl2 = Calendar.getInstance();
		cl2.setTime(bd);
		Calendar cl3 = Calendar.getInstance();

		// 判断起始日期为周几
		if (cl1.get(Calendar.DAY_OF_WEEK) == 1) {
			time.add(a);
		} else {
			cl1.add(Calendar.DAY_OF_MONTH, 8 - cl1.get(Calendar.DAY_OF_WEEK));
			time.add(a + "~" + sdf.format(cl1.getTime()));
		}
		do {
			cl1.add(Calendar.DAY_OF_MONTH, 1);
			String s = sdf.format(cl1.getTime());
			cl1.add(Calendar.DAY_OF_MONTH, 6);
			time.add(s + "~" + sdf.format(cl1.getTime()));
			cl3.setTime(cl1.getTime());
			cl3.add(Calendar.DAY_OF_MONTH, 7);
		} while (cl3.getTime().getTime() < cl2.getTime().getTime());
		cl1.add(Calendar.DAY_OF_MONTH, 1);
		String s = sdf.format(cl1.getTime());
		if (s.equals(b)) {
			time.add(s);
		} else {
			time.add(s + "~" + b);
		}
		ListIterator<String> iterator = time.listIterator();
		while (iterator.hasNext()) {
			String t = iterator.next();
			if (t.length() > 10) {
				String t1 = t.substring(0, t.indexOf("~"));
				String t2 = t.substring(t.indexOf("~") + 1);
				// 借助SimpleDateFormat类将时间字符串转成日期这种方法最全面（注意如果能保证两个字符串格式一样，
				// 且都是用上面的形式表示的（即是2010-07-16 13:01:01，而不是2007-7-16 1:1:1），
				// 这样，可以直接用字符串比较就可以了，也可以long longstr1 =
				// Long.valueOf(str1.replaceAll("[-\\s:]",""));）
				Date m = null;
				Date n = null;
				try {
					m = sdf.parse(t1);
					n = sdf.parse(t2);
				} catch (Exception e) {
					e.printStackTrace();
				}
				Long result1 = m.getTime() - n.getTime();
				if (result1 > 0) {
					iterator.remove();
					continue;
				}
				Long result2 = n.getTime() - bd.getTime();
				if (result2 > 0) {
					t2 = b;
					t = t1 + "~" + t2;

				}
				if (t1.equals(t2)) {
					t = t1;
				}
			}

			System.out.println(t);

		}

		return time;

	}

	public static void main(String[] args) throws ParseException {
		System.out.println(DateUtils.formatDate(DateUtils.getDateBefore(new Date(), 0 )));
	}

	/**
	 * 
	 * 给定开始时间和结束时间，把中间的日期按照周分组
	 * 
	 * 第二种方法
	 */

	public static List<String> groupByWeek2(String a, String b) throws ParseException {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date ad = sdf.parse(a);
		Date bd = sdf.parse(b);

		Calendar cl1 = Calendar.getInstance();
		cl1.setTime(ad);
		Calendar cl2 = Calendar.getInstance();
		cl2.setTime(bd);
		Map<Integer, List<String>> result = new HashMap<Integer, List<String>>();

		int num = 0;

		while (true) {
			if (cl2.compareTo(cl1) <= 0) {
				break;
			}

			int count = 7;

			if (num == 0) {
				int day = cl1.get(Calendar.DAY_OF_WEEK) - 1;
				day = day == 0 ? 7 : day;
				count = 7 - day + 1;
			}
			if (!result.containsKey(num)) {
				result.put(num, new ArrayList<String>());
			}

			for (int i = 0; i < count; i++) {
				result.get(num).add(sdf.format(cl1.getTime()));
				cl1.add(Calendar.DAY_OF_WEEK, 1);
				if (cl2.compareTo(cl1) <= 0) {
					break;
				}
			}
			num++;
		}

		List<String> time = new ArrayList<String>();

		for (Map.Entry<Integer, List<String>> entry : result.entrySet()) {
			List<String> temp = entry.getValue();
			String str = temp.get(0) + "~" + temp.get(temp.size() - 1);
			time.add(str);
		}

		return time;
	}

	/**
	 * 
	 * 第三中方法
	 * 
	 */

	static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

	static List<String[]> getType(Date sd, Date ed) {
		long days = (ed.getTime() - sd.getTime()) / 3600 / 24 / 1000;
		List<String[]> list = new ArrayList<>();
		if (days == 0) {
			list.add(new String[] { df.format(sd), df.format(sd) });
			return list;
		}
		Calendar instance = Calendar.getInstance();
		instance.setTime(sd);
		int i = instance.get(Calendar.DAY_OF_WEEK);
		int fsi = 7 - i + 1;
		long iiv = days - fsi;

//天数
		long d = iiv / 7;

		instance.add(Calendar.DAY_OF_YEAR, fsi);

		list.add(new String[] { df.format(sd), df.format(instance.getTime()) });

		String[] ne;
		for (long k = 0; k < d; k++) {
			instance.add(Calendar.DAY_OF_YEAR, 1);
			Date start = instance.getTime();
			instance.add(Calendar.DAY_OF_YEAR, 6);
			Date end = instance.getTime();
			ne = new String[] { df.format(start), df.format(end) };
			list.add(ne);
		}

		instance.add(Calendar.DAY_OF_YEAR, 1);
		list.add(new String[] { df.format(instance.getTime()), df.format(ed) });

		return list;
	}

	public static List<String> myGroupByWeek(String a, String b) throws ParseException {
		List<String[]> type = getType(df.parse(a), df.parse(b));
		List<String> myList = new ArrayList<>();
		for (int i = 0; i < type.size(); i++) {
			String[] strings = type.get(i);
			String my = strings[0] + "~" + strings[1];
			myList.add(my);

		}
		return myList;
	}

}
